package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.DeviceMediaBindDeviceDTO;
import com.itlong.cloud.POJO.DTO.property.DeviceMediaRemoveWallBindDeviceDTO;
import com.itlong.cloud.POJO.DTO.property.DeviceMediaWallSaveDTO;
import com.itlong.cloud.POJO.DTO.property.DeviceMediaWallUpdateDTO;
import com.itlong.cloud.POJO.PO.DeviceBusinessChangeLogPO;
import com.itlong.cloud.POJO.PO.DeviceMediaInfoPO;
import com.itlong.cloud.POJO.PO.DeviceMediaWallPO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaAttacheFileInfoVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaBindDeviceVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaInfoVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaWallInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.CloudIntercomTypeEnum;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.property.dao.IDeviceMediaInfoDao;
import com.itlong.cloud.property.dao.IDeviceMediaWallDao;
import com.itlong.cloud.property.service.IDeviceMediaWallService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 * 门口机设备多媒体信息处理接口实现.
 * </desc>
 *
 * @createDate 2017-10-23
 */
@Service
public class DeviceMediaWallServiceImpl implements IDeviceMediaWallService{

    @Autowired
    private IDeviceMediaInfoDao iDeviceMediaInfoDao; //设备多媒体信息数据库访问对象
    @Autowired
    private IDeviceMediaWallDao iDeviceMediaWallDao; //围墙机设备多媒体服务信息数据库访问对象

    @Autowired
    private MessageSender messageSender; //RabitMQ发送
    /**
     * <desc>
     *      保存单个围墙机设备多媒体信息
     * </desc>
     *
     * @param deviceMediaWallSaveDTO  保存围墙机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author Lix
     * @createDate 2017-10-23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer saveDeviceMediaInfo(DeviceMediaWallSaveDTO deviceMediaWallSaveDTO) throws Exception {
        String mediaId = LogicIdUtil.bussinessId();
        Date saveTime = new Date();

        DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
        deviceMediaInfoPO.setMediaId(mediaId);
        deviceMediaInfoPO.setProjectId(deviceMediaWallSaveDTO.getProjectId());
        deviceMediaInfoPO.setTitle(deviceMediaWallSaveDTO.getTitle());
        deviceMediaInfoPO.setChildrenType(CloudIntercomTypeEnum.WALL.getType());
        deviceMediaInfoPO.setType(deviceMediaWallSaveDTO.getType());
        deviceMediaInfoPO.setContent(deviceMediaWallSaveDTO.getContent());
        deviceMediaInfoPO.setStatus(deviceMediaWallSaveDTO.getStatus());
        deviceMediaInfoPO.setAttacheFile(deviceMediaWallSaveDTO.getAttacheFiles());
        deviceMediaInfoPO.setAttacheFileUrl(deviceMediaWallSaveDTO.getAttacheFileUrls()); // iDeviceMediaInfoService.saveBase64Picture(deviceMediaWallSaveDTO.getBase64Pictures()));
        deviceMediaInfoPO.setAttacheFileMd5(deviceMediaWallSaveDTO.getAttacheFileMd5());
        deviceMediaInfoPO.setCreateTime(saveTime);
        deviceMediaInfoPO.setUpdateTime(saveTime);

        //保存设备多媒体信息和围墙机关联信息搭配数据库（事务保护）
        int intRes = this.saveDeviceMediaInfoToDB(deviceMediaInfoPO,deviceMediaWallSaveDTO);



        //仅多媒体资源添加时状态为启用时才通知云对讲更新
        if (NumberHandlerUtil.isEqual(deviceMediaInfoPO.getStatus(),DataStatusEnum.NORMAL.getType())){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("projectId",deviceMediaWallSaveDTO.getProjectId());
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA,jsonObject,deviceMediaWallSaveDTO.getProjectId());
            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",deviceBusinessChangeLogPOS);
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
        return intRes;
    }

    /**
     * <desc>
     *      保存单个围墙机设备多媒体信息
     * </desc>
     *
     * @param deviceMediaInfoPO  数据库多媒体对象
     * @param deviceMediaWallSaveDTO  保存围墙机设备多媒体信息数据传输对象
     * @return 受影响的行数
     * @author LewisLouis
     * @createDate 2018-02-25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveDeviceMediaInfoToDB(DeviceMediaInfoPO deviceMediaInfoPO,DeviceMediaWallSaveDTO deviceMediaWallSaveDTO) throws Exception {

        iDeviceMediaInfoDao.save(SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_SAVE));

        //批量保存围墙机多媒体资源-围墙机关联信息
        List<Map<String,Object>> batchParams = new ArrayList<>();
        for (DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO:deviceMediaWallSaveDTO.getBindDeviceInfos())
        {
            DeviceMediaWallPO deviceMediaWallPO = new DeviceMediaWallPO();
            deviceMediaWallPO.setMediaId(deviceMediaInfoPO.getMediaId());
            deviceMediaWallPO.setProjectId(deviceMediaWallSaveDTO.getProjectId());
            deviceMediaWallPO.setDeviceUnique(deviceMediaBindDeviceDTO.getDeviceUnique());
            deviceMediaWallPO.setSn(deviceMediaBindDeviceDTO.getSn());
            deviceMediaWallPO.setCreateTime(deviceMediaInfoPO.getCreateTime());
            deviceMediaWallPO.setUpdateTime(deviceMediaInfoPO.getCreateTime());
            deviceMediaWallPO.setStatus(DataStatusEnum.NORMAL.getType());
            batchParams.add(SqlUtil.durableData(deviceMediaWallPO, PlatformConstants.TABLE_SAVE));
        }
        //保存围墙机关联信息
        int intRes = iDeviceMediaWallDao.batchSave(batchParams);
        return  intRes;

    }



    /**
    * <desc>
    *    更新围墙机多媒体信息及关联的设备信息.
    * </desc>
    *
    * @param deviceMediaWallUpdateDTO 更新围墙机多媒体信息数据传输对象
    * @return 受影响的行数
    * @author LewisLouis
    * @createDate 2017-11-23
    */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer updateDeviceMediaInfo(DeviceMediaWallUpdateDTO deviceMediaWallUpdateDTO) throws Exception {

        //保存设备多媒体信息
        Date updateTime = new Date();
        DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
        deviceMediaInfoPO.setMediaId(deviceMediaWallUpdateDTO.getMediaId());
        deviceMediaInfoPO.setProjectId(null);
        deviceMediaInfoPO.setTitle(deviceMediaWallUpdateDTO.getTitle());
        deviceMediaInfoPO.setChildrenType(CloudIntercomTypeEnum.WALL.getType());
        deviceMediaInfoPO.setType(deviceMediaWallUpdateDTO.getType());
        deviceMediaInfoPO.setContent(deviceMediaWallUpdateDTO.getContent());
        deviceMediaInfoPO.setStatus(deviceMediaWallUpdateDTO.getStatus());
        deviceMediaInfoPO.setAttacheFile(deviceMediaWallUpdateDTO.getAttacheFiles());
        deviceMediaInfoPO.setAttacheFileUrl(deviceMediaWallUpdateDTO.getAttacheFileUrls());
        deviceMediaInfoPO.setAttacheFileMd5(deviceMediaWallUpdateDTO.getAttacheFileMd5());
        deviceMediaInfoPO.setCreateTime(null);
        deviceMediaInfoPO.setUpdateTime(updateTime);

        //保存设备多媒体信息(事务保护)
        Integer intRes = this.updateDeviceMediaInfoToDB(deviceMediaInfoPO,deviceMediaWallUpdateDTO);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectId",deviceMediaWallUpdateDTO.getProjectId());
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA,jsonObject,deviceMediaWallUpdateDTO.getProjectId());
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",deviceBusinessChangeLogPOS);
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        return  intRes;
    }

    /**
     * <desc>
     *    更新围墙机多媒体信息及关联的设备信息到数据库.
     * </desc>
     * @param deviceMediaInfoPO 设备对媒体信息数据库对象
     * @param deviceMediaWallUpdateDTO 更新围墙机多媒体信息数据传输对象
     * @return 受影响的行数
     * @author LewisLouis
     * @createDate 2017-11-23
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateDeviceMediaInfoToDB(DeviceMediaInfoPO deviceMediaInfoPO,DeviceMediaWallUpdateDTO deviceMediaWallUpdateDTO) throws Exception {
        iDeviceMediaInfoDao.update(SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_UPDATE));
        //修改围墙机关联信息

        //先删除原来的所有多媒体资源-围墙机设备关系
        iDeviceMediaWallDao.removeOne(deviceMediaWallUpdateDTO.getMediaId());

        List<Map<String,Object>> batchParams = new ArrayList<>();
        for (DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO:deviceMediaWallUpdateDTO.getBindDeviceInfos())
        {
            DeviceMediaWallPO deviceMediaWallPO = new DeviceMediaWallPO();
            deviceMediaWallPO.setMediaId(deviceMediaWallUpdateDTO.getMediaId());
            deviceMediaWallPO.setProjectId(deviceMediaWallUpdateDTO.getProjectId());
            deviceMediaWallPO.setDeviceUnique(deviceMediaBindDeviceDTO.getDeviceUnique());
            deviceMediaWallPO.setSn(deviceMediaBindDeviceDTO.getSn());
            deviceMediaWallPO.setCreateTime(deviceMediaInfoPO.getUpdateTime());
            deviceMediaWallPO.setUpdateTime(deviceMediaInfoPO.getUpdateTime());
            deviceMediaWallPO.setStatus(DataStatusEnum.NORMAL.getType());
            batchParams.add(SqlUtil.durableData(deviceMediaWallPO, PlatformConstants.TABLE_SAVE));
        }
        //保存围墙机关联信息
        Integer intRes = iDeviceMediaWallDao.batchSave(batchParams);

        return intRes;
    }

    /**
     * <desc>
     * 根据多媒体资源Id获取围墙机多媒体资源及其对应的地址列表.
     * </desc>
     *
     * @param mediaId 多媒体资源ID
     * @return 围墙机多媒体资源及其对应的地址列表
     * @author LewisLouis
     * @createDate 2017-11-21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public DeviceMediaWallInfoVO getOneMediaInfo(String mediaId) {
        DeviceMediaInfoVO mediaInfoVO = iDeviceMediaInfoDao.getOneMediaInfo(mediaId);
        if (mediaInfoVO == null){
            return  null;
        }
        DeviceMediaWallInfoVO deviceMediaWallInfoVO = new DeviceMediaWallInfoVO();
        BeanUtils.copyProperties(mediaInfoVO,deviceMediaWallInfoVO);

        List<DeviceMediaAttacheFileInfoVO> deviceMediaAttacheFileInfoVOS = new ArrayList<>();
        List<String> attacheFileUrls = castStrToListByCommaChar(mediaInfoVO.getAttacheFileUrl());
        List<String> attacheFileNames = castStrToListByCommaChar(mediaInfoVO.getAttacheFile());
        List<String> attacheFileMd5s = castStrToListByCommaChar(mediaInfoVO.getAttacheFileMd5());;
        for (int fileIndex = 0; fileIndex< attacheFileNames.size();fileIndex++){
            String fileName = attacheFileNames.get(fileIndex);
            DeviceMediaAttacheFileInfoVO deviceMediaAttacheFileInfoVO = new DeviceMediaAttacheFileInfoVO();
            deviceMediaAttacheFileInfoVO.setFileName(fileName);
            if (attacheFileUrls.size() > fileIndex){
                deviceMediaAttacheFileInfoVO.setAttacheFileUrl(attacheFileUrls.get(fileIndex));
            }
            if (attacheFileMd5s.size() > fileIndex){
                deviceMediaAttacheFileInfoVO.setFileMd5(attacheFileMd5s.get(fileIndex));
            }
            deviceMediaAttacheFileInfoVOS.add(deviceMediaAttacheFileInfoVO);
        }
        deviceMediaWallInfoVO.setAttacheFiles(deviceMediaAttacheFileInfoVOS);
        List<DeviceMediaBindDeviceVO> deviceMediaBindDeviceVOS = iDeviceMediaWallDao.getOneMediaWallInfo(mediaId);
        deviceMediaWallInfoVO.setBindDeviceInfos(deviceMediaBindDeviceVOS);

        return deviceMediaWallInfoVO;
    }

    /**
     * <desc>
     * 删除围墙机多媒体资源-与指定设备的关系.
     * </desc>
     *
     * @param deviceMediaRemoveWallBindDeviceDTO 需要删除的围墙机多媒体资源关联的部分设备关系.
     * @return 受影响的行数
     * @author LewisLouis
     * @createDate 2017-11-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer removeMediaWallRelation(DeviceMediaRemoveWallBindDeviceDTO deviceMediaRemoveWallBindDeviceDTO) {
        return iDeviceMediaWallDao.removeMediaWallRelation(deviceMediaRemoveWallBindDeviceDTO);
    }



    /**
    * <desc>
    *    将逗号分隔的源字符串转换为List.
    * </desc>
    *
    * @param sourceStr 逗号分隔的源字符串
    * @return String列表
    * @author LewisLouis
    * @createDate 2017-11-25
    */
    private List<String> castStrToListByCommaChar(String sourceStr){
        List<String> resultList;
        if (!StringUtils.isBlank(sourceStr)){
            resultList =  Arrays.asList(sourceStr.split(","));
        } else
        {
            resultList = new ArrayList<>();
        }
        return  resultList;
    }


}
